#ifndef INCLUDE_SHM_NOTIFY_H
#define INCLUDE_SHM_NOTIFY_H

#include <stdint.h>
#include <stddef.h>  // 用于NULL定义

#ifndef SHM_API
#ifdef SHM_STATIC
#define SHM_API  static
#else
#ifdef __cplusplus
#define SHM_API  extern "C"
#else
#define SHM_API  extern
#endif
#endif
#endif

enum {
    SHM_NOTIFY_ERROR_OK,
    SHM_NOTIFY_ERROR_INVALID_PARAM = -1,
    SHM_NOTIFY_ERROR_OPEN = -2,
    SHM_NOTIFY_ERROR_WAIT = -3,
    SHM_NOTIFY_ERROR_SEND = -4,
    SHM_NOTIFY_ERROR_TIMEOUT = -5  // 新增超时错误码
};

typedef struct shm_notify {
    void* sem;  // POSIX信号量指针（sem_t*）
} shm_notify_t;

SHM_API int shm_notify_open(shm_notify_t* notify, const char* name);
SHM_API int shm_notify_close(shm_notify_t* notify);

SHM_API int shm_notify_wait(shm_notify_t* notify, uint32_t timeout_ms);
SHM_API int shm_notify_send(shm_notify_t* notify);

#endif // INCLUDE_SHM_NOTIFY_H

#ifdef SHM_NOTIFY_IMPLEMENTATION

#include <semaphore.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

SHM_API int shm_notify_open(shm_notify_t* notify, const char* name) {
    if (!notify || !name || strlen(name) == 0) {
        return SHM_NOTIFY_ERROR_INVALID_PARAM;
    }

    // 创建或打开命名信号量（初始值0，权限0666）
    sem_t* sem = sem_open(name, O_CREAT | O_EXCL | O_RDWR, 0666, 0);
    if (sem == SEM_FAILED) {
        // 如果信号量已存在，尝试打开
        if (errno == EEXIST) {
            sem = sem_open(name, O_RDWR);
        }
        if (sem == SEM_FAILED) {
            return SHM_NOTIFY_ERROR_OPEN;
        }
    }

    notify->sem = sem;
    return SHM_NOTIFY_ERROR_OK;
}

SHM_API int shm_notify_close(shm_notify_t* notify) {
    if (!notify || !notify->sem) {
        return SHM_NOTIFY_ERROR_INVALID_PARAM;
    }

    sem_t* sem = (sem_t*)notify->sem;
    sem_close(sem);
    notify->sem = NULL;

    return SHM_NOTIFY_ERROR_OK;
}

SHM_API int shm_notify_wait(shm_notify_t* notify, uint32_t timeout_ms) {
    if (!notify || !notify->sem) {
        return SHM_NOTIFY_ERROR_INVALID_PARAM;
    }

    sem_t* sem = (sem_t*)notify->sem;

    if (timeout_ms == 0) {
        // 无限等待
        if (sem_wait(sem) == -1) {
            return SHM_NOTIFY_ERROR_WAIT;
        }
    } else {
        // 超时等待：计算绝对时间
        struct timespec ts;
        if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
            return SHM_NOTIFY_ERROR_WAIT;
        }

        ts.tv_sec += timeout_ms / 1000;
        ts.tv_nsec += (timeout_ms % 1000) * 1000000;
        
        // 处理纳秒溢出
        if (ts.tv_nsec >= 1000000000) {
            ts.tv_sec += 1;
            ts.tv_nsec -= 1000000000;
        }

        // 带超时的等待
        int ret = sem_timedwait(sem, &ts);
        if (ret == -1) {
            if (errno == ETIMEDOUT) {
                return SHM_NOTIFY_ERROR_TIMEOUT;  // 超时
            }
            return SHM_NOTIFY_ERROR_WAIT;
        }
    }

    return SHM_NOTIFY_ERROR_OK;
}

SHM_API int shm_notify_send(shm_notify_t* notify) {
    if (!notify || !notify->sem) {
        return SHM_NOTIFY_ERROR_INVALID_PARAM;
    }

    sem_t* sem = (sem_t*)notify->sem;
    if (sem_post(sem) == -1) {
        return SHM_NOTIFY_ERROR_SEND;
    }

    return SHM_NOTIFY_ERROR_OK;
}

#endif // SHM_NOTIFY_IMPLEMENTATION
